#pragma once
#include "Connection.hpp"
using AcceptCallBack = std::function<void(int)>;//获取新连接后的回调
//Acceptor模块是对Socket模块，Channel模块的⼀个整体封装
class Acceptor
{
public:
    //不能将启动读事件监控放到构造函数中，必须在设置回调函数后，再去启动，
    //否则可能造成启动监控后立即触发读事件，处理读事件但读事件处理的回调函数还没有被设置（导致新连接得不到处理导致资源泄漏）
    Acceptor(EventLoop* loop, int port)
        :_loop(loop)
        ,_socket(CreateServer(port))
        ,_channel(loop, _socket.GetFd())
    {
        _channel.SetReadCallback(std::bind(&Acceptor::HandlerRead, this));//设置可读事件的回调
    }
    //获取新连接后的回调函数的设置
    void SetAcceptCallback(const AcceptCallBack& callback) { _acceptCallBack = callback; }
    //启动读事件监控
    void Listen() { _channel.EnableRead();}
private:
    //监听套接字的读事件回调处理函数（获取新连接，调用_acceptCallBack函数进行新连接的处理）
    void HandlerRead()
    {
        int newfd = _socket.Accept();//监听套接字的可读事件就是获取新连接
        if (newfd < 0) { return; }//获取失败
        if (_acceptCallBack) { _acceptCallBack(newfd); }
    }
    //创建新连接
    int CreateServer(int port)
    {
        bool ret = _socket.CreateServer(port);
        assert(ret == true);
        return _socket.GetFd();
    }
private:
    Socket _socket;//监听套接字的Socket对象
    EventLoop* _loop;//用于对监听套接字进行事件监控
    Channel _channel;//用于对监听套接字进行事件管理（处理监听事件）
    AcceptCallBack _acceptCallBack;//获取新连接后的回调函数
};